﻿#include <xy/ais/builder.h>
#include <xy/geom/bspline_curve.h>
#include <xy/geom/bspline_surface.h>

#include "frame.h"

using namespace xy;
using namespace xy::geom;

// 应用程序类
class GLApp : public CWinApp
{
  public:
    virtual BOOL InitInstance()
    {
#ifndef NDEBUG
        AllocConsole();
        FILE *pCout;
        freopen_s(&pCout, "CONOUT$", "w", stdout);
        freopen_s(&pCout, "CONOUT$", "w", stderr);

        SetConsoleOutputCP(CP_UTF8);
#endif

        // 创建流程
        CSingleDocTemplate *pTemplate =
            new CSingleDocTemplate(IDR_MENU1, RUNTIME_CLASS(GLDoc), RUNTIME_CLASS(GLFrame), RUNTIME_CLASS(GLView));

        // 添加模板
        AddDocTemplate(pTemplate);

        // 创建新的窗口
        OnFileNew();
        m_pMainWnd->ShowWindow(SW_SHOW);
        m_pMainWnd->UpdateWindow();
        m_pMainWnd->SetWindowText(L"GLFW");
        m_pMainWnd->SetWindowPos(NULL, 0, 0, 1200, 800, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);

        // 构建 GLFW 上下文
        InitGL();

        return TRUE;
    }

    void InitGL()
    {
        RECT rect;
        auto frame = (CFrameWnd *)m_pMainWnd;
        frame->GetWindowRect(&rect);

        // 创建 context
        auto view = (GLView *)frame->GetActiveView();
        auto aisContext = view->CreateContext(rect.right - rect.left, rect.bottom - rect.top)->context();

        auto obj = builder::create_point(vec3{0.0, 2.0, 0.0});
        aisContext->add_object(obj);

        std::vector<vec3> cpts = {{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 1.0, 0.0}};
        std::vector<double> knots = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
        auto cur = std::make_shared<bspline_curve<3>>(std::move(cpts), std::move(knots), 3);
        auto obj2 = builder::create_curve(cur);
        aisContext->add_object(obj2);

        std::vector<vec3> P(5 * 6);
        for (int i = 0; i < 5; i++)
            for (int j = 0; j < 6; j++)
                P[i * 6 + j] = vec3((double)i, sin(i + j), (double)j);

        std::vector<double> uknots({0, 0.1, 0.2, 0.4, 0.6, 1, 2, 3});
        std::vector<double> vknots({0, 0.1, 0.15, 0.2, 0.5, 0.8, 1, 2, 3, 3});
        auto surf = std::make_shared<bspline_surface<3>>(std::move(P), std::move(uknots), std::move(vknots), 2, 3);
        auto obj3 = builder::create_surface(surf);
        aisContext->add_object(obj3);
    }

    ~GLApp()
    {
#ifndef NDEBUG
        FreeConsole();
#endif
    }
};

// 应用程序对象的全局变量
GLApp theApp;